package com.baitiaojun.system.admin.service.permission.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baitiaojun.common.utils.collection.CollectionUtils;
import com.baitiaojun.common.utils.object.ObjectUtils;
import com.baitiaojun.system.admin.dto.MenuTreeDTO;
import com.baitiaojun.system.admin.mapper.permission.MenuMapper;
import com.baitiaojun.system.admin.pojo.SysMenuDO;
import com.baitiaojun.system.admin.service.permission.MenuService;
import com.baitiaojun.system.admin.service.permission.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, SysMenuDO> implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleService roleService;

    @Override
    public Set<SysMenuDO> getPermsByUserId(String userId) {
        return menuMapper.selectPermsByUserId(userId);
    }

    @Override
    public List<MenuTreeDTO> queryMenuTreeByRoleIds(Long[] roleIds) {
        if (roleIds.length == 0) {
            return new ArrayList<>();
        }

        List<SysMenuDO> sysMenuDOS;
        if (roleService.isAnySupperAdmin(roleIds)) {
            return queryMenuAll();
        } else {
            sysMenuDOS = menuMapper.selectMenuTreeByRoleId(Arrays.stream(roleIds).collect(Collectors.toList()));
            sysMenuDOS = sysMenuDOS.stream().distinct().collect(Collectors.toList());
        }
        return buildMenuTree(sysMenuDOS);
    }

    @Override
    public List<MenuTreeDTO> queryMenuAll() {
        List<SysMenuDO> sysMenuDOS = menuMapper.selectAll();
        if (CollectionUtils.isEmpty(sysMenuDOS)) {
            return new ArrayList<>();
        }
        return sysMenuDOS.stream().distinct()
                .map(sysMenu -> BeanUtil.copyProperties(sysMenu, MenuTreeDTO.class))
                .collect(Collectors.toList());
    }

    private List<MenuTreeDTO> buildMenuTree(List<SysMenuDO> sysMenus) {
        //定义集合用来保存顶层菜单
        List<MenuTreeDTO> menus = new ArrayList<>();
        //转为map集合
        Map<Long, MenuTreeDTO> sysMenuDTOMap = sysMenus.stream()
                .map(sysMenu -> BeanUtil.copyProperties(sysMenu, MenuTreeDTO.class))
                .collect(Collectors.toMap(MenuTreeDTO::getMenuId, menuTreeDTO -> menuTreeDTO));
        //遍历菜单
        for (Map.Entry<Long, MenuTreeDTO> menuMap : sysMenuDTOMap.entrySet()) {
            MenuTreeDTO sysMenu = menuMap.getValue(); //获取当前菜单
            MenuTreeDTO parentMenu = sysMenuDTOMap.get(sysMenu.getParentId()); //获取父级菜单
            //如果当前菜单的父级菜单是null说明是顶层菜单, 直接添加
            if (ObjectUtils.isNull(parentMenu)) {
                menus.add(sysMenu);
            } else {
                //如果不是定价菜单,就添加到当前节点到父菜单的子菜单
                List<MenuTreeDTO> children = parentMenu.getChildren();
                children.add(sysMenu);
            }
        }
        return menus;
    }
}
